package com.atwisdom.star.core.bsl.customized.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.atwisdom.star.common.vo.ActionData;
import com.atwisdom.star.common.vo.JsonResult;
import com.atwisdom.star.common.vo.ResultInfo;
import com.atwisdom.star.common.vo.StatusCode;
import com.atwisdom.star.core.bsl.customized.PurchaseBslService;
import com.atwisdom.star.core.bsl.event.EventUtil;
import com.atwisdom.star.core.bsl.modelClass.logic.LogicInstanceBslService;
import com.atwisdom.star.core.dao.pojo.modelClass.hier.HierInstance;
import com.atwisdom.star.core.dsl.modelClass.hier.HierInstanceDslService;
import com.atwisdom.star.core.dsl.modelClass.logic.LogicInstanceDslService;
import com.atwisdom.star.exception.pojo.BusinessException;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 
 * @Date: 2023-08-28 10:54
 */
@Slf4j
@AllArgsConstructor
@Service
public class PurchaseBslServiceImpl implements PurchaseBslService {
    private LogicInstanceDslService logicInstanceDslService;
    private LogicInstanceBslService logicInstanceBslService;
    private HierInstanceDslService hierInstanceDslService;
    private EventUtil eventUtil;

    /**
     * 根据采购计划明细，查询供应商价表
     * @return
     */
    // @Override
    public JSONObject querySupplierPrice1(String supplierCode, String materialBcode)  {
        List<JSONObject> supplierPriceList = logicInstanceDslService.query("effectiveStatus = 1 and supplier_code = '" + supplierCode + "'",
                "SupplierPrice", null, "parentId = 'u8y72p2ho4g00' and material_bcode = '"+materialBcode+"'");
        if (CollectionUtil.isEmpty(supplierPriceList)) {
            return null;
        }
        JSONArray hierArray = supplierPriceList.get(0).getJSONObject("hier").getJSONArray("content");
        if (CollectionUtil.isEmpty(hierArray)) {
            return null;
        }
        return hierArray.getJSONObject(0).getJSONObject("values");
    }

    /**
     * 根据采购计划明细，查询供应商价表
     * @return
     */
    @Override
    public JSONObject querySupplierPrice(String supplierCode, String materialBcode)  {
        List<JSONObject> supplierPriceList = logicInstanceDslService.query("effectiveStatus = 1 and supplier_code = '" + supplierCode + "'", "SupplierPrice");
        if (CollectionUtil.isEmpty(supplierPriceList)) {
            throw new BusinessException(StatusCode.ERROR_DATA_ERROR.getCode(), "供应商编码:"+supplierCode+",背番"+materialBcode+"价表不存在");
        }
        JSONObject supplierPriceJson = supplierPriceList.get(0);
        List<HierInstance> hierInstanceList = hierInstanceDslService.queryByContainerId("logic", supplierPriceJson.getLong("id"), "SupplierPrice", "parentId = 'u8y72p2ho4g00' and material_bcode = '" + materialBcode + "'");
        if (CollectionUtil.isEmpty(hierInstanceList)) {
             throw new BusinessException(StatusCode.ERROR_DATA_ERROR.getCode(), "供应商编码:"+supplierCode+",背番"+materialBcode+"价表不存在");
        }
        return hierInstanceList.get(0).getValues();
    }


    /**
     * 按指定主表记录的Hier记录分组，并生成下游单据，要求下游单据的Hier与上游单据Hier的属性一致
     * @param actionData
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public ResultInfo<?> createOrder(ActionData<JSONObject> actionData) {
        String model = actionData.getModel();
        Long containerId = actionData.getInstanceId();
        String groupByKey = actionData.getGroupKey();
        String parentNodeId = actionData.getParentId();

        // 查询主表记录
        JSONObject logicInstanceJson = logicInstanceDslService.queryJsonById(containerId);
        Map<Object, List<HierInstance>> resultMap = hierInstanceDslService.fetchByParentNodeIdAndGroupBy(model, containerId, parentNodeId, groupByKey);
        // 根据上面的查询可以得出，需要分解成3条新记录，如何创建新的实例呢？ 新的主表记录的model, className, 字段映射关系
        List<JSONObject> resultJsonList = new ArrayList<>();
        resultMap.forEach((k,v)->{
            JSONObject resultJson = new JSONObject();
            JSONObject tempInstanceJson = ObjectUtil.cloneByStream(logicInstanceJson);
            resultJson.put("master", tempInstanceJson);
            BigDecimal totalMoney = BigDecimal.ZERO;
            BigDecimal totalMoneyNonTax = BigDecimal.ZERO;
            for (int i = 0; i < v.size(); i++) {
                HierInstance hierInstance = v.get(i);
                JSONObject childValues = hierInstance.getValues();
                String supplierCode = childValues.getString("supplier_code");
                String materialBcode = childValues.getString("material_bcode");
                BigDecimal price = childValues.getBigDecimal("price");
                BigDecimal priceNonTax = childValues.getBigDecimal("priceNonTax");
                BigDecimal taxRate = childValues.getBigDecimal("taxRate");
                JSONObject supplierPriceValues = querySupplierPrice(supplierCode, materialBcode);
                if (price == null) {
                    price = supplierPriceValues == null? BigDecimal.ZERO : supplierPriceValues.getBigDecimal("price");
                    price = price != null ? price : BigDecimal.ZERO;
                }
                if (priceNonTax == null) {
                    priceNonTax = supplierPriceValues == null? BigDecimal.ZERO : supplierPriceValues.getBigDecimal("priceNonTax");
                    priceNonTax = priceNonTax != null ? priceNonTax : BigDecimal.ZERO;
                }
                BigDecimal processingFee = childValues.getBigDecimal("processingFee");
                if (processingFee == null) {
                    processingFee = supplierPriceValues == null? BigDecimal.ZERO : supplierPriceValues.getBigDecimal("processingFee");
                    processingFee = processingFee != null ? processingFee : BigDecimal.ZERO;
                }

                if (taxRate == null) {
                    taxRate = supplierPriceValues == null ? BigDecimal.ZERO : supplierPriceValues.getBigDecimal("taxRate");
                    taxRate = taxRate != null ? taxRate :  BigDecimal.ZERO;
                }

                childValues.put("taxRate", taxRate);
                childValues.put("price", price);
                childValues.put("priceNonTax", priceNonTax);
                BigDecimal quantity = childValues.getBigDecimal("quantity");
                processingFee = quantity.multiply(processingFee);
                childValues.put("processingFee", processingFee);
                BigDecimal money = quantity.multiply(price);
                BigDecimal moneyNonTax = quantity.multiply(priceNonTax);
                childValues.put("money", money);
                childValues.put("moneyNonTax", moneyNonTax);
                totalMoney = totalMoney.add(money);
                totalMoneyNonTax = totalMoneyNonTax.add(moneyNonTax);
            }
            resultJson.put("slave", v);
            tempInstanceJson.getJSONObject("values").put("money", totalMoney);
            tempInstanceJson.getJSONObject("values").put("moneyNonTax", totalMoneyNonTax);
            resultJsonList.add(resultJson);
        });
        JSONObject dataJson = actionData.getData().get(0);
        JSONObject targetJson = dataJson.getJSONObject("target");
        List propertyMapList = dataJson.getJSONArray("propertyMapList");
        propertyMapList.add("master.values.money:master.money");
        propertyMapList.add("master.values.moneyNonTax:master.moneyNonTax");

        logicInstanceBslService.copy1(resultJsonList, targetJson, propertyMapList);
        return JsonResult.success(resultJsonList);
    }

}
